from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required  # 如果需要登录才能访问
from django.utils import timezone
from django.db.models import Q,ObjectDoesNotExist
from datetime import timedelta, datetime
from .models import Article,ArticleGroup
from .forms import ArticleForm, ContentItemFormSet
from .forms import MissionForm
import json
from .models import (
    Mission, MissionDetail, MissionStatus, MissionBasicInfo, MissionContent,
    Article, TaskRelation, Astronaut, LaunchSite, Encyclopedia, EncyclopediaGroup,
    Institution, InstitutionRelation, MissionInstitutionMember, KnowledgeQuestion  # 添加KnowledgeQuestion导入
)
from .models import MissionContent,MissionStatus,MissionBasicInfo
from .models import LaunchSite
from rest_framework.views import APIView,status
from rest_framework.response import Response
from .serializers import MissionSerializer
from .models import EncyclopediaGroup
from .serializers import EncyclopediaGroupSerializer
from .serializers import MissionSerializer, ArticleGroupSerializer,EncyclopediaGroupSerializer, LaunchSiteSerializer,Institution, KnowledgeQuestionSerializer  # 添加KnowledgeQuestionSerializer导入
from django.core.exceptions import ObjectDoesNotExist
from .models import Institution, InstitutionRelation

def home(request):
    return render(request, 'myapp01/home.html', {})

def dashboard(request):
    return render(request, 'myapp01/dashboard.html')

def article_list(request):
    articles = Article.objects.all().order_by('-created_at')  # 获取所有文章并按创建时间降序排列
    return render(request, 'myapp01/article_list.html', {'articles': articles})

def article_create(request):
    if request.method == "POST":
        article_form = ArticleForm(request.POST)
        formset = ContentItemFormSet(request.POST)
        if article_form.is_valid() and formset.is_valid():
            article = article_form.save(commit=False)
            data = [form.cleaned_data.get('json_data') for form in formset if form.cleaned_data.get('json_data')]
            try:
                parsed_data = [json.loads(item) for item in data]  # 解析JSON字符串
                article.content = parsed_data
                article.save()
                return redirect('article_list')
            except json.JSONDecodeError:
                formset.non_form_errors().append("请确保所有输入都是有效的JSON格式")
    else:
        article_form = ArticleForm()
        formset = ContentItemFormSet()  # 初始化至少一个空内容块
    
    return render(request, 'myapp01/article_form.html', {'article_form': article_form, 'formset': formset})


def article_detail(request, pk):
    article = get_object_or_404(Article, pk=pk)
    return render(request, 'myapp01/article_detail.html', {'article': article})

def article_edit(request, pk):
    article = get_object_or_404(Article, pk=pk)
    if request.method == "POST":
        article_form = ArticleForm(request.POST, instance=article)  # 使用instance参数
        formset = ContentItemFormSet(request.POST)
        if article_form.is_valid() and formset.is_valid():
            article = article_form.save(commit=False)
            data = [form.cleaned_data.get('json_data') for form in formset if form.cleaned_data.get('json_data')]
            try:
                parsed_data = [json.loads(item) for item in data]  # 解析JSON字符串
                article.content = parsed_data
                article.save()
                return redirect('article_list')
            except json.JSONDecodeError:
                formset.non_form_errors().append("请确保所有输入都是有效的JSON格式")
    else:
        # 初始化表单和表单集时使用现有文章的数据
        initial_content = [{"json_data": json.dumps(item)} for item in article.content]
        article_form = ArticleForm(instance=article)
        formset = ContentItemFormSet(initial=initial_content)
    
    return render(request, 'myapp01/article_form.html', {'article_form': article_form, 'formset': formset})

def article_delete(request, pk):
    article = get_object_or_404(Article, pk=pk)
    if request.method == "POST":
        article.delete()
        return redirect('article_list')
    return render(request, 'myapp01/article_confirm_delete.html', {'article': article})

def mission_list(request):
    missions=Mission.objects.all().order_by('launch_time_utc')
    return render(request, 'myapp01/mission_list.html', {'missions': missions})

def mission_create(request):
    if request.method == "POST":
        form = MissionForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('mission_list')
    else:
        form = MissionForm()
    return render(request, 'myapp01/mission_form.html', {'form': form})

def mission_edit(request, pk):
    mission = get_object_or_404(Mission, pk=pk)
    if request.method == "POST":
        form = MissionForm(request.POST, instance=mission)
        if form.is_valid():
            form.save()
            return redirect('mission_list')
    else:
        form = MissionForm(instance=mission)
    return render(request, 'myapp01/mission_form.html', {'form': form})

def mission_copy(request, pk):
    if request.method == "GET":
        # 获取原始任务对象
        original_mission = get_object_or_404(Mission, pk=pk)
        # 创建新任务并保存
        new_mission = Mission.objects.create(
            mission_name=original_mission.mission_name + " - 复制",
            institution=original_mission.institution,
            image_url=original_mission.image_url,
            launch_time=original_mission.launch_time,
            launch_time_utc=original_mission.launch_time_utc,
            status=original_mission.status,
        )
        return redirect('mission_edit', pk=new_mission.pk)
    else:
        return HttpResponse("不支持的方法", status=405)
    
def mission_delete(request, pk):
    if request.method == "POST":
        # 获取原始任务对象
        mission = get_object_or_404(Mission, pk=pk)
        mission.delete()
        return redirect('mission_list')  # 假设任务列表页面的名字是'mission_list'
    else:
        return HttpResponse("不支持的方法", status=405)

class MissionInfoListView(APIView):
    def get(self, request):
        query_type = request.query_params.get('type', None)
        now = timezone.now()
        one_day_ago = now - timedelta(days=1)

        if query_type == 'upcoming':
            missions = Mission.objects.filter(
                Q(launch_time_utc__gt=now) | Q(status='预计')
            ).order_by('launch_time_utc')
        elif query_type == 'historical':
            missions = Mission.objects.filter(
                launch_time_utc__lt=now
            ).exclude(status='预计').order_by('-launch_time_utc')
        elif query_type == 'recommend':
            # 删除所有复杂逻辑，直接按倒序返回所有推荐任务
            missions = Mission.objects.filter(recommend=True).order_by('-launch_time_utc')
        else:
            missions = Mission.objects.all().order_by('-launch_time_utc')

        serializer = MissionSerializer(missions, many=True)
        return Response(serializer.data)
    
class MissionInfoView(APIView):
    def get(self, request):
        mission_id = request.query_params.get('id', None)
        if mission_id is not None:
            try:
                mission = Mission.objects.get(pk=mission_id)
            except Mission.DoesNotExist:
                return Response(status=status.HTTP_404_NOT_FOUND)
            
            serializer = MissionSerializer(mission)
            return Response(serializer.data)
        else:
            return Response({"error": "ID parameter is required"}, status=status.HTTP_400_BAD_REQUEST)
        
class NextMissionView(APIView):
    def get(self, request):
        # 获取所有状态为'scheduled'且launch_time_utc大于当前时间的任务
        next_mission = Mission.objects.filter(status='预计', launch_time_utc__gt=timezone.now()).order_by('launch_time_utc').first()
        
        if next_mission is not None:
            serializer = MissionSerializer(next_mission)
            return Response(serializer.data)
        else:
            return Response({"message": "No upcoming missions"}, status=404)
        
class MissionDetailInfoView(APIView):
    def get(self, request):
        mission_id = request.query_params.get('id', None)
        if mission_id is None:
            return Response({"error": "ID parameter is required"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            mission_detail = MissionDetail.objects.get(mission_id=mission_id)
        except MissionDetail.DoesNotExist:
            return Response({"error": "Mission detail not found"}, status=status.HTTP_404_NOT_FOUND)

        # 获取发射场信息
        launch_site_data = None
        if hasattr(mission_detail, 'launch_site') and mission_detail.launch_site:
            launch_site_data = {
                "id": mission_detail.launch_site.id,
                "name": mission_detail.launch_site.name,
                "location": mission_detail.launch_site.location,
                "image_url": mission_detail.launch_site.image_url
            }

        # 构造返回数据
        related_groups = []
        for group in mission_detail.new_related_groups.all():
            # 查询该任务组包含的任务数量
            mission_count = group.related_missions.count()
            related_groups.append({
                "id": group.relation_id,
                "name": group.name,
                "description": group.description,
                "mission_count": mission_count,
                "image_url": group.image_url  # 添加image_url字段
            })

        # 获取乘组成员信息
        crew_members = []
        for member in mission_detail.crew_members.through.objects.filter(mission_detail=mission_detail).order_by('order'):
            crew_members.append({
                "id": member.astronaut.id,
                "name": member.astronaut.chinese_name,
                "image_url": member.astronaut.image_url,
                "role": member.role
            })

        # 获取机构信息
        institutions = []
        institution_members = MissionInstitutionMember.objects.filter(mission_detail=mission_detail).select_related('institution').order_by('order')
        
        for member in institution_members:
            if member.institution:
                institutions.append({
                    "role": member.role,
                    "institution": {
                        "id": member.institution.id,
                        "name": member.institution.name,
                        "logo": member.institution.logo
                    }
                })

        # 获取文章信息
        articles_data = []
        
        # 首先添加直接关联的文章（按日期从新到旧排序）
        direct_articles = mission_detail.articles.all().order_by('-date')
        
        # 如果有直接关联的文章组，添加其文章（最多5篇最新的）
        article_group_articles = []
        if mission_detail.article_group:
            article_group_articles = mission_detail.article_group.articles.all().order_by('-date')[:5]
        
        # 合并文章列表：先直接关联的文章，再文章组的文章
        all_articles = list(direct_articles) + list(article_group_articles)
        
        # 使用ArticleSerializer序列化文章
        from .serializers import ArticleSerializer
        article_serializer = ArticleSerializer(all_articles, many=True)
        articles_data = article_serializer.data

        return Response({
            "mission_id": mission_id,
            "related_groups": related_groups,
            "crew_members": crew_members,
            "institutions": institutions,
            "launch_site": launch_site_data,
            "articles": articles_data  # 直接返回文章列表
        }, status=status.HTTP_200_OK)
    
class TaskGroupMissionsView(APIView):
    def get(self, request):
        # 获取 group_id 和 limit 参数
        group_id = request.query_params.get('group_id', None)
        limit = request.query_params.get('limit', None)

        if group_id is None:
            return Response({"error": "Group ID parameter is required"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 获取关联任务组
            task_group = TaskRelation.objects.get(relation_id=group_id)
        except TaskRelation.DoesNotExist:
            return Response({"error": "Task group not found"}, status=status.HTTP_404_NOT_FOUND)

        # 获取关联的任务
        missions = task_group.related_missions.all()

        # 如果提供了 limit 参数，则限制任务数量
        if limit is not None:
            try:
                limit = int(limit)  # 确保 limit 是整数
                if limit <= 0:
                    raise ValueError("Limit must be a positive integer")
                missions = missions[:limit]  # 截取前 limit 条任务
            except ValueError:
                return Response({"error": "Invalid limit parameter. Must be a positive integer."}, status=status.HTTP_400_BAD_REQUEST)

        # 序列化任务数据
        serializer = MissionSerializer(missions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)
    
class MissionDetailsBriefIntroView(APIView):
    def get(self, request):
        # 获取前端传来的任务 ID 参数
        mission_id = request.query_params.get('id', None)
        if not mission_id:
            return Response({"error": "缺少任务 ID 参数"}, status=400)

        try:
            # 根据任务 ID 查找 Mission 实例
            mission = Mission.objects.get(id=mission_id)
        except ObjectDoesNotExist:
            return Response({"error": "未找到对应的任务"}, status=404)

        try:
            # 获取关联的 MissionStatus、MissionBasicInfo 和 MissionContent 数据
            status_data = MissionStatus.objects.get(mission=mission)
            basic_info_data = MissionBasicInfo.objects.get(mission=mission)
            content_data = MissionContent.objects.get(mission=mission)
        except ObjectDoesNotExist as e:
            return Response({"error": f"缺少关联数据: {str(e)}"}, status=404)

        # 获取发射场名称，优先使用任务详情中的发射场
        launch_site_name = basic_info_data.launch_site
        try:
            mission_detail = MissionDetail.objects.get(mission=mission)
            if mission_detail.launch_site:
                launch_site_name = mission_detail.launch_site.name
        except ObjectDoesNotExist:
            pass  # 如果没有任务详情，使用基本信息中的发射场
        
        # 构造返回的 JSON 数据
        response_data = {
            "status": {
                "status": status_data.status,
                "description": status_data.description,
                "color": status_data.color,
            },
            "basic_info": {
                "type": "mission_basic_info",
                "country": basic_info_data.country,
                "institution": basic_info_data.institution,
                "rocket_name": basic_info_data.rocket_name,
                "payload_info": basic_info_data.payload_info,
                "launch_site": launch_site_name,  # 使用修改后的发射场名称
                "launch_time": mission.launch_time,
                "mini_tags": basic_info_data.mini_tags,
                "badge_url": basic_info_data.badge_url,  # 新增徽章URL字段
                "badge_text": basic_info_data.badge_text,  # 新增徽章说明字段
            },
            "content": content_data.content,
        }

        return Response(response_data)

class LaunchStatisticsView(APIView):
    """
    处理 /api/launch_statistics/ 请求，返回2025年全球和中国的发射统计数据。
    """

    def get(self, request):
        # 设置2025年的时间范围
        start_date = datetime(2025, 1, 1, tzinfo=timezone.utc)
        current_date = timezone.now()
        
        # 获取2025年所有可统计的任务
        missions_2025 = Mission.objects.filter(
            launch_time_utc__gte=start_date,
            launch_time_utc__lte=current_date,
            is_countable=True
        )
        
        # 全球统计
        global_success = missions_2025.filter(status='成功').count()
        global_failure = missions_2025.filter(status='失败').count()
        global_anomaly = missions_2025.filter(status='异常').count()
        
        # 中国统计 - 通过MissionBasicInfo的country字段
        china_missions = missions_2025.filter(basic_info__country='china')
        china_success = china_missions.filter(status='成功').count()
        china_failure = china_missions.filter(status='失败').count()
        china_anomaly = china_missions.filter(status='异常').count()
        
        # 构造返回数据
        response_data = {
            "global_statistics": {
                "success": global_success,
                "failure": global_failure,
                "anomaly": global_anomaly,
                "total": global_success + global_failure + global_anomaly
            },
            "china_statistics": {
                "success": china_success,
                "failure": china_failure,
                "anomaly": china_anomaly,
                "total": china_success + china_failure + china_anomaly
            }
        }
        
        return Response(response_data)


class LaunchSiteDetailView(APIView):
    def get(self, request):
        # 获取前端传来的发射场 ID 参数
        site_id = request.query_params.get('id', None)
        if not site_id:
            return Response({"error": "缺少发射场 ID 参数"}, status=400)

        try:
            # 根据发射场 ID 查找 LaunchSite 实例
            launch_site = LaunchSite.objects.get(id=site_id)
        except ObjectDoesNotExist:
            return Response({"error": "未找到对应的发射场"}, status=404)

        # 计算年发射数（2025年1月1日至今）
        start_date = datetime(2025, 1, 1, tzinfo=timezone.utc)
        current_date = timezone.now()
        
        # 查询该发射场在指定时间范围内的发射数
        # 通过MissionDetail关联查询，筛选有launch_site且时间在范围内的任务
        annual_launches = Mission.objects.filter(
            任务名称__launch_site=launch_site,  # 使用正确的 related_name
            launch_time_utc__gte=start_date,
            launch_time_utc__lte=current_date
        ).count()

        # 构造返回的 JSON 数据
        response_data = {
            "id": launch_site.id,
            "name": launch_site.name,
            "location": launch_site.location,
            "active_pads": launch_site.active_pads,
            "latitude_type": launch_site.latitude_type,
            "location_type": launch_site.location_type,
            "image_url": launch_site.image_url,
            "basic_info": launch_site.basic_info,
            "content": launch_site.content,
            "annual_launches": annual_launches,  # 新增年发射数字段
        }

        return Response(response_data)


class EncyclopediaGroupDetailView(APIView):
    """
    获取百科内容组的完整结构化数据
    """
    def get(self, request):
        # 获取前端传来的内容组 ID 参数
        group_id = request.query_params.get('id', None)
        if not group_id:
            return Response({"error": "缺少内容组 ID 参数"}, status=400)

        try:
            # 根据内容组 ID 查找 EncyclopediaGroup 实例
            # 使用 prefetch_related 优化查询性能
            encyclopedia_group = EncyclopediaGroup.objects.prefetch_related(
                'sections__items__encyclopedia'
            ).get(id=group_id)
        except ObjectDoesNotExist:
            return Response({"error": "未找到对应的内容组"}, status=404)

        # 使用序列化器序列化数据
        serializer = EncyclopediaGroupSerializer(encyclopedia_group)
        return Response(serializer.data)


class LaunchSiteListView(APIView):
    """
    获取所有发射场列表，按order字段排序
    """
    def get(self, request):
        # 按order字段升序排列获取所有发射场
        launch_sites = LaunchSite.objects.all().order_by('order')
        
        # 手动构造返回数据，匹配前端序列化字段名称
        launch_sites_data = []
        for site in launch_sites:
            # 计算年发射数（2025年1月1日至今）
            start_date = datetime(2025, 1, 1, tzinfo=timezone.utc)
            current_date = timezone.now()
            
            # 查询该发射场在指定时间范围内的发射数
            annual_launches = Mission.objects.filter(
                任务名称__launch_site=site,  # 使用正确的 related_name
                launch_time_utc__gte=start_date,
                launch_time_utc__lte=current_date
            ).count()
            
            site_data = {
                "id": site.id,
                "name": site.name,
                "location": site.location,
                "active_pads": site.active_pads,
                "latitude_type": site.latitude_type,
                "location_type": site.location_type,
                "image_url": site.image_url,
                "basic_info": site.basic_info,
                "content": site.content,
                "order": site.order,
                "annual_launches": annual_launches
            }
            launch_sites_data.append(site_data)
        
        # 直接返回数组，不包装额外字段
        return Response(launch_sites_data)

class InstitutionDetailView(APIView):
    def get(self, request):
        institution_id = request.query_params.get('id', None)
        if not institution_id:
            return Response({"error": "缺少机构 ID 参数"}, status=400)

        try:
            institution = Institution.objects.get(id=institution_id)
        except ObjectDoesNotExist:
            return Response({"error": "未找到对应的机构"}, status=404)

        # 获取相关机构信息
        related_institutions = []
        relations = InstitutionRelation.objects.filter(from_institution=institution).select_related('to_institution').order_by('order')
        
        for relation in relations:
            if relation.to_institution:
                related_institutions.append({
                    "role": relation.role,
                    "institution": {
                        "id": relation.to_institution.id,
                        "name": relation.to_institution.name,
                        "logo": relation.to_institution.logo
                    }
                })

        # 构造返回数据
        response_data = {
            "id": institution.id,
            "name": institution.name,
            "logo": institution.logo,
            "country": institution.country,
            "nature": institution.nature,
            "image_url": institution.image_url,
            "basic_info": institution.basic_info,
            "content": institution.content,
            "order": institution.order,
            "related_institutions": related_institutions
        }

        return Response(response_data)

class KnowledgeQuestionView(APIView):
    def get(self, request):
        question_id = request.query_params.get('id', None)
        if question_id is None:
            return Response({"error": "ID parameter is required"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            question = KnowledgeQuestion.objects.get(id=question_id)
        except KnowledgeQuestion.DoesNotExist:
            return Response({"error": "Question not found"}, status=status.HTTP_404_NOT_FOUND)

        serializer = KnowledgeQuestionSerializer(question)
        return Response(serializer.data)

class ArticleGroupDetailView(APIView):
    """
    获取文章内容组的完整结构化数据
    """
    def get(self, request):
        # 获取前端传来的内容组 ID 参数
        group_id = request.query_params.get('id', None)
        if not group_id:
            return Response({"error": "缺少内容组 ID 参数"}, status=400)

        # 新增功能：如果groupid是-1，则返回所有时间在2024年1月1日及以后的文章
        if group_id == '-1':
            # 定义2024年1月1日的日期
            date_threshold = datetime(2024, 1, 1, tzinfo=timezone.utc)
            # 获取所有时间在2024年1月1日及以后的文章，按日期倒序排列
            articles = Article.objects.filter(date__gte=date_threshold).order_by('-date')
            
            # 使用ArticleSerializer序列化文章
            from .serializers import ArticleSerializer
            serializer = ArticleSerializer(articles, many=True)
            
            # 构造与ArticleGroupSerializer相同格式的响应数据
            response_data = {
                "id": -1,
                "title": "2024年及以后文章",
                "description": "所有时间在2024年1月1日及以后发布的文章",
                "articles": serializer.data,
                "articles_count": len(serializer.data)
            }
            
            return Response(response_data)

        try:
            # 根据内容组 ID 查找 ArticleGroup 实例
            article_group = ArticleGroup.objects.prefetch_related('articles').get(id=group_id)
        except ObjectDoesNotExist:
            return Response({"error": "未找到对应的内容组"}, status=404)

        # 使用序列化器序列化数据
        serializer = ArticleGroupSerializer(article_group)
        return Response(serializer.data)


class LaunchSiteMissionsView(APIView):
    """
    根据发射场ID返回该发射场的发射任务
    要求任务状态必须为成功、失败或异常之一
    按时间倒序排序
    """
    def get(self, request):
        # 获取前端传来的发射场 ID 参数
        site_id = request.query_params.get('site_id', None)
        if not site_id:
            return Response({"error": "缺少发射场 ID 参数"}, status=400)

        try:
            # 根据发射场 ID 查找 LaunchSite 实例
            launch_site = LaunchSite.objects.get(id=site_id)
        except ObjectDoesNotExist:
            return Response({"error": "未找到对应的发射场"}, status=404)

        # 查询该发射场的任务，状态必须为成功、失败或异常之一，按时间倒序排序
        missions = Mission.objects.filter(
            任务名称__launch_site=launch_site,
            status__in=['成功', '失败', '异常']
        ).order_by('-launch_time_utc')

        # 使用序列化器序列化数据
        serializer = MissionSerializer(missions, many=True)
        return Response(serializer.data)